<template>
	<div class="pos_r h100" v-loading="authLoading">
		<div class="authorization owoy padding_l_20">
			<!-- 菜单权限 -->
			<div class="margin_l_25 margin_b_5">菜单权限</div>
			<el-tree :data="menuDatas" :show-checkbox="!authBtnLoading" node-key="id" ref="tree"
				:default-expand-all="false" :default-checked-keys="checkeds" :props="defaultProps"></el-tree>
			<!-- 操作权限 -->
			<div class="margin_l_25 margin_t_20 margin_b_5">操作权限（云函数）</div>
			<el-checkbox-group class="dflex_wrap padding_l_25" v-model="operCheckList">
				<el-checkbox v-for="(item, i) in operationAuthDatas" :label="item.permission_id" :key="i"
					:checked="item.checked" @change="perCheckboxChange(item)"
					:disabled="roleObj.role_id == 'admin' || authBtnLoading">
					{{ item.permission_name }}
				</el-checkbox>
			</el-checkbox-group>
			<!-- 消息通知 -->
			<div class="margin_l_25 margin_t_20 margin_b_5">消息通知</div>
			<el-checkbox-group class="dflex_wrap padding_l_25" v-model="messageCheckList">
				<el-checkbox v-for="(item, i) in messageDatas" :label="item.message_id" :key="i" :checked="item.checked"
					@change="messageCheckboxChange(item)" :disabled="roleObj.role_id == 'admin' || authBtnLoading">
					{{ item.title }}
				</el-checkbox>
			</el-checkbox-group>
		</div>
		<div class="btn pos_a">
			<el-button :disabled="roleObj.role_id == 'admin' || authLoading || authBtnLoading" round
				icon="el-icon-delete" class="table-btn" @click="resetChecked">清空
			</el-button>
			<el-button :disabled="roleObj.role_id == 'admin' || authLoading || authBtnLoading" round icon="el-icon-sort"
				class="table-btn" @click="checkInvert">反选
			</el-button>
			<el-button :disabled="roleObj.role_id == 'admin' || authLoading" @click="submit" :loading="authBtnLoading"
				round icon="el-icon-check" class="confirm-btn">提交</el-button>
			<el-button :disabled="authBtnLoading" round icon="el-icon-back" class="return-btn" @click="returnPage">返回
			</el-button>
		</div>
	</div>
</template>

<script>
	const __menu = 'opendb-admin-menus';
	const __role = 'uni-id-roles';
	const __per = 'uni-id-permissions';
	const __message = 'wmzmall-message-type';
	export default {
		props: {
			roleObj: {
				type: Object,
				default () {
					return {};
				}
			}
		},
		data() {
			return {
				authLoading: false,
				menuDatas: [],
				menuChecks: [],
				authBtnLoading: false,
				checkeds: [],
				menuIds: [],
				permissionIds: [],
				defaultProps: {
					children: 'children',
					label: 'label',
					data: 'data'
				},
				// 操作权限
				operCheckList: [],
				operationAuthDatas: [],
				// 消息通知
				messageCheckList: [],
				messageDatas: []
			};
		},
		methods: {
			// 获取数据
			loadData() {
				this.authLoading = true;
				this.$db[__per]
					.noshopid()
					.noaction()
					.tolist({
						rows: 100,
						loading: false
					}).then(res => {
						if (res.code == 200) {
							// 获取操作权限没有选择菜单的数据
							const operDatas = res.datas.filter(x => x.menu_id == '');
							// 判断此角色为管理员默认勾选 或者 判断此角色是否勾选
							operDatas.forEach(x => {
								x.checked = this.roleObj.role_id == 'admin' || (this.roleObj.permission &&
									this.roleObj.permission.findIndex(d => d == x.permission_id) != -1);
							});
							this.operationAuthDatas = operDatas;

							// 赋值给菜单权限
							this.getMenu(res.datas.filter(x => x.menu_id));
						}
					});

				this.$db[__message]
					.noshopid()
					.noaction()
					.where({
						type: 1,
						state: 1
					}).tolist({
						rows: 100,
						loading: false
					}).then(res => {
						if (res.code == 200) {
							// 判断此角色为管理员默认勾选 或者 判断此角色是否勾选
							res.datas.forEach(x => {
								x.checked = this.roleObj.role_id == 'admin' || (this.roleObj.permission &&
									this.roleObj.permission.findIndex(d => d == x.message_id) != -1);
							});
							this.messageDatas = res.datas;
						}
					});
			},
			// 菜单权限
			getMenu(pers) {
				// 获取启用的菜单
				this.$db[__menu]
					.noshopid()
					.noaction()
					.where({
						enable: true
					})
					.tolist({
						rows: 100,
						orderby: 'sort asc',
						loading: false
					})
					.then(res => {
						if (res.code == 200) {
							let children;
							res.datas.forEach(data => {
								children = [];
								// parent_id == '' 代表 主菜单
								if (data.parent_id == '') {
									// 判断此角色为管理员默认勾选 或者 判断此角色是否勾选
									if (this.roleObj.role_id == 'admin' || (this.roleObj.permission && this
											.roleObj.permission.findIndex(x => x == data._id) != -1)) {
										// 赋值勾选ID
										this.menuChecks.push(data._id);
									}

									// 获取子菜单
									children = this.getSubs(data, pers, res.datas);

									if (children.length <= 0) {
										children = null;
									}

									data.type = 'module';

									this.menuDatas.push({
										id: data._id,
										label: data.name,
										data: data,
										disabled: this.roleObj.role_id == 'admin',
										children: children
									});

									this.menuIds.push({
										id: data._id
									});
								}
							});

							this.$nextTick(() => {
								this.checkeds = this.menuChecks;
							});
						}
						this.authLoading = false;
					});
			},
			// 子菜单
			getSubs(menu, pers, datas) {
				let arr = datas.filter(x => x.parent_id == menu._id);
				let subs = [];
				let menuPres = [];
				arr.forEach(x => {
					x.type = 'module';

					// 判断此角色为管理员默认勾选 或者 判断此角色是否勾选
					if (this.roleObj.role_id == 'admin' || (this.roleObj.permission && this.roleObj.permission
							.findIndex(d => d == x._id) != -1)) {
						// 赋值勾选ID
						this.menuChecks.push(x._id);
					} else if (this.roleObj.role_id != 'admin') {
						// 不是管理员 并且 已勾选
						if (this.menuChecks.findIndex(d => d == menu._id) != -1) {
							// 取消勾选
							this.menuChecks.splice(this.menuChecks.findIndex(d => d == menu._id), 1);
						}
					}

					// 获取操作权限
					menuPres = this.getMenuPers(menu._id, x._id, pers);

					if (menuPres && menuPres.length > 0) {
						// x.name += `【操作权限（云函数） × ${menuPres.length}】`;
					} else {
						menuPres = null;
					}

					subs.push({
						id: x._id,
						label: x.name,
						data: x,
						disabled: this.roleObj.role_id == 'admin',
						children: menuPres
					});

					this.menuIds.push({
						id: x._id
					});
				});

				return subs;
			},
			// 操作权限
			getMenuPers(pid, menuId, pers) {
				// 获取 相对应的 菜单的操作权限
				const arrs = pers.filter(x => x.menu_id == menuId);
				if (!arrs.length) return null;

				let menuPers = [];
				let auths = [];

				menuPers.push({
					type: 'module_auth',
					id: menuId + '-view',
					label: '查看权限',
					data: {},
					disabled: this.roleObj.role_id == 'admin',
					children: null
				});

				if (this.roleObj.role_id == 'admin' || (this.roleObj.permission && this.roleObj.permission.findIndex(d =>
						d == menuId + '-view') != -1)) {
					this.menuChecks.push(menuId + '-view');
				}

				arrs.forEach(x => {
					x.type = 'module_oper';

					auths.push({
						id: x._id,
						label: x.permission_name,
						data: x,
						disabled: this.roleObj.role_id == 'admin',
						children: null
					});

					// 判断此角色为管理员默认勾选 或者 判断此角色是否勾选
					if (this.roleObj.role_id == 'admin' || (this.roleObj.permission && this.roleObj.permission
							.findIndex(d => d == x.permission_id) != -1)) {
						// 赋值勾选ID
						this.menuChecks.push(x._id);
					} else if (this.roleObj.role_id != 'admin') {
						// 不是管理员 并且 已勾选
						if (this.menuChecks.findIndex(d => d == menuId) != -1) {
							// 取消勾选
							this.menuChecks.splice(this.menuChecks.findIndex(d => d == menuId), 1);
							// 取消勾选
							this.menuChecks.splice(this.menuChecks.findIndex(d => d == pid), 1);
						}
					}

					this.menuIds.push({
						id: x._id
					});
				});

				menuPers.push({
					type: 'module_auth',
					id: menuId + '-oper',
					label: `操作权限（云函数） × ${arrs.length}`,
					data: {},
					disabled: this.roleObj.role_id == 'admin',
					children: auths
				});

				this.menuIds.push({
					id: menuId + '-view'
				});

				this.menuIds.push({
					id: menuId + '-oper'
				});

				return menuPers;
			},
			perCheckboxChange(item) {
				item.checked = this.operCheckList.findIndex(x => x == item.permission_id) != -1;
			},
			messageCheckboxChange(item) {
				item.checked = this.messageCheckList.findIndex(x => x == item.message_id) != -1;
			},
			// 清空
			resetChecked() {
				this.$refs.tree.setCheckedKeys([]);
				this.operCheckList = [];
				this.messageCheckList = [];

				this.operationAuthDatas.forEach(x => {
					x.checked = false;
				});

				this.messageDatas.forEach(x => {
					x.checked = false;
				});
			},
			// 反选
			checkInvert() {
				let checkNodes = this.$refs.tree.getCheckedNodes(false, true);
				let halfCheckKeys = this.$refs.tree.getHalfCheckedKeys();

				this.menuIds.forEach(x => {
					if (halfCheckKeys.find(key => key == x.id)) return;

					this.$refs.tree.setChecked(x.id, !checkNodes.find(res => res.id == x.id), true);
				});

				this.operationAuthDatas.forEach(x => {
					if (x.checked) {
						this.operCheckList.splice(this.operCheckList.findIndex(d => d == x.permission_id), 1);
					} else {
						this.operCheckList.push(x.permission_id);
					}

					x.checked = !x.checked;
				});

				this.messageDatas.forEach(x => {
					if (x.checked) {
						this.messageCheckList.splice(this.messageCheckList.findIndex(d => d == x.message_id), 1);
					} else {
						this.messageCheckList.push(x.message_id);
					}

					x.checked = !x.checked;
				});
			},
			// 提交
			submit() {
				this.authBtnLoading = true;
				let halfCheckKeys = this.$refs.tree.getHalfCheckedKeys();
				this.permissionIds = ['sys/menu/auth', ...halfCheckKeys];

				this.$refs.tree.getCheckedNodes().forEach(x => {
					if (x.data.type == 'module') {
						this.permissionIds.push(x.data._id);
					} else if (x.data.type == 'module_oper') {
						this.permissionIds.push(x.data.permission_id);
					} else if (x.type == 'module_auth') {
						this.permissionIds.push(x.id);
					}
				});

				// 处理未选中 查看权限 情况
				halfCheckKeys.forEach(x => {
					// 半选中状态下的菜单，存在 查看权限
					if (this.menuIds.find(m => m.id == (x + '-view'))) {
						// 判断是否已勾选，是否存在 this.permissionIds 中
						if (!this.permissionIds.includes(x + '-view')) {
							// 不存在
							// 删除半选中状态下的菜单 id
							this.permissionIds.splice(this.permissionIds.findIndex(m => m == x), 1);
						}
					}
				});

				this.operationAuthDatas
					.filter(x => x.checked)
					.forEach(x => {
						this.permissionIds.push(x.permission_id);
					});

				this.messageDatas
					.filter(x => x.checked)
					.forEach(x => {
						this.permissionIds.push(x.message_id);
					});

				this.$db[__role]
					.noshopid()
					.noaction()
					.update(this.roleObj._id, {
						permission: this.permissionIds
					}, false).then(res => {
						if (res.code == 200) {
							this.$message({
								message: '操作成功',
								type: 'success'
							});
							this.$emit('fatherMethod', true);
						}
						this.authBtnLoading = false;
					});
			},
			returnPage() {
				this.$emit('fatherMethod', false);
			}
		},
		created() {
			this.loadData();
		}
	};
</script>

<style>
	.authorization {
		height: 90%;
	}

	.btn {
		bottom: 15px;
		right: 15px;
	}

	>>>.el-checkbox {
		margin-right: 10px;
	}

	>>>.el-checkbox-group {
		height: initial;
		margin: 0;
	}

	>>>.el-checkbox-group .el-checkbox {
		width: 50%;
		margin: 6px 0;
	}
</style>
